/*
 * Crypto-JS v2.5.1
 * http://code.google.com/p/crypto-js/
 * (c) 2009-2011 by Jeff Mott. All rights reserved.
 * http://code.google.com/p/crypto-js/wiki/License
 */

(typeof Crypto == "undefined" || !Crypto.util) && function () {
    var e = self.Crypto = {},
        g = e.util = {
            rotl: function (a, b) {
                return a << b | a >>> 32 - b
            },
            rotr: function (a, b) {
                return a << 32 - b | a >>> b
            },
            endian: function (a) {
                if (a.constructor == Number) return g.rotl(a, 8) & 16711935 | g.rotl(a, 24) & 4278255360;
                for (var b = 0; b < a.length; b++) a[b] = g.endian(a[b]);
                return a
            },
            randomBytes: function (a) {
                for (var b = []; a > 0; a--) b.push(Math.floor(Math.random() * 256));
                return b
            },
            bytesToWords: function (a) {
                for (var b = [], c = 0, d = 0; c < a.length; c++, d += 8) b[d >>> 5] |= a[c] << 24 -
                    d % 32;
                return b
            },
            wordsToBytes: function (a) {
                for (var b = [], c = 0; c < a.length * 32; c += 8) b.push(a[c >>> 5] >>> 24 - c % 32 & 255);
                return b
            },
            bytesToHex: function (a) {
                for (var b = [], c = 0; c < a.length; c++) b.push((a[c] >>> 4).toString(16)), b.push((a[c] & 15).toString(16));
                return b.join("")
            },
            hexToBytes: function (a) {
                for (var b = [], c = 0; c < a.length; c += 2) b.push(parseInt(a.substr(c, 2), 16));
                return b
            },
            bytesToBase64: function (a) {
                if (typeof btoa == "function") return btoa(f.bytesToString(a));
                for (var b = [], c = 0; c < a.length; c += 3)
                    for (var d = a[c] << 16 | a[c + 1] << 8 |
                            a[c + 2], e = 0; e < 4; e++) c * 8 + e * 6 <= a.length * 8 ? b.push("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(d >>> 6 * (3 - e) & 63)) : b.push("=");
                return b.join("")
            },
            base64ToBytes: function (a) {
                if (typeof atob == "function") return f.stringToBytes(atob(a));
                for (var a = a.replace(/[^A-Z0-9+\/]/ig, ""), b = [], c = 0, d = 0; c < a.length; d = ++c % 4) d != 0 && b.push(("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(a.charAt(c - 1)) & Math.pow(2, -2 * d + 8) - 1) << d * 2 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(a.charAt(c)) >>>
                    6 - d * 2);
                return b
            }
        },
        e = e.charenc = {};
    e.UTF8 = {
        stringToBytes: function (a) {
            return f.stringToBytes(unescape(encodeURIComponent(a)))
        },
        bytesToString: function (a) {
            return decodeURIComponent(escape(f.bytesToString(a)))
        }
    };
    var f = e.Binary = {
        stringToBytes: function (a) {
            for (var b = [], c = 0; c < a.length; c++) b.push(a.charCodeAt(c) & 255);
            return b
        },
        bytesToString: function (a) {
            for (var b = [], c = 0; c < a.length; c++) b.push(String.fromCharCode(a[c]));
            return b.join("")
        }
    }
}();

// Auxiliary functions
function FF(a, b, c, d, x, s, t) {
    var n = a + (b & c | ~b & d) + (x >>> 0) + t;
    return ((n << s) | (n >>> (32 - s))) + b;
}

function GG(a, b, c, d, x, s, t) {
    var n = a + (b & d | c & ~d) + (x >>> 0) + t;
    return ((n << s) | (n >>> (32 - s))) + b;
}

function HH(a, b, c, d, x, s, t) {
    var n = a + (b ^ c ^ d) + (x >>> 0) + t;
    return ((n << s) | (n >>> (32 - s))) + b;
}

function II(a, b, c, d, x, s, t) {
    var n = a + (c ^ (b | ~d)) + (x >>> 0) + t;
    return ((n << s) | (n >>> (32 - s))) + b;
}

function md5(m, hash) {
    var a = hash[0],
        b = hash[1],
        c = hash[2],
        d = hash[3];

    for (var i = 0; i < m.length; i += 16) {

        var aa = a,
            bb = b,
            cc = c,
            dd = d;
        a = FF(a, b, c, d, m[i + 0], 7, -680876936);
        d = FF(d, a, b, c, m[i + 1], 12, -389564586);
        c = FF(c, d, a, b, m[i + 2], 17, 606105819);
        b = FF(b, c, d, a, m[i + 3], 22, -1044525330);
        a = FF(a, b, c, d, m[i + 4], 7, -176418897);
        d = FF(d, a, b, c, m[i + 5], 12, 1200080426);
        c = FF(c, d, a, b, m[i + 6], 17, -1473231341);
        b = FF(b, c, d, a, m[i + 7], 22, -45705983);
        a = FF(a, b, c, d, m[i + 8], 7, 1770035416);
        d = FF(d, a, b, c, m[i + 9], 12, -1958414417);
        c = FF(c, d, a, b, m[i + 10], 17, -42063);
        b = FF(b, c, d, a, m[i + 11], 22, -1990404162);
        a = FF(a, b, c, d, m[i + 12], 7, 1804603682);
        d = FF(d, a, b, c, m[i + 13], 12, -40341101);
        c = FF(c, d, a, b, m[i + 14], 17, -1502002290);
        b = FF(b, c, d, a, m[i + 15], 22, 1236535329);
        a = GG(a, b, c, d, m[i + 1], 5, -165796510);
        d = GG(d, a, b, c, m[i + 6], 9, -1069501632);
        c = GG(c, d, a, b, m[i + 11], 14, 643717713);
        b = GG(b, c, d, a, m[i + 0], 20, -373897302);
        a = GG(a, b, c, d, m[i + 5], 5, -701558691);
        d = GG(d, a, b, c, m[i + 10], 9, 38016083);
        c = GG(c, d, a, b, m[i + 15], 14, -660478335);
        b = GG(b, c, d, a, m[i + 4], 20, -405537848);
        a = GG(a, b, c, d, m[i + 9], 5, 568446438);
        d = GG(d, a, b, c, m[i + 14], 9, -1019803690);
        c = GG(c, d, a, b, m[i + 3], 14, -187363961);
        b = GG(b, c, d, a, m[i + 8], 20, 1163531501);
        a = GG(a, b, c, d, m[i + 13], 5, -1444681467);
        d = GG(d, a, b, c, m[i + 2], 9, -51403784);
        c = GG(c, d, a, b, m[i + 7], 14, 1735328473);
        b = GG(b, c, d, a, m[i + 12], 20, -1926607734);
        a = HH(a, b, c, d, m[i + 5], 4, -378558);
        d = HH(d, a, b, c, m[i + 8], 11, -2022574463);
        c = HH(c, d, a, b, m[i + 11], 16, 1839030562);
        b = HH(b, c, d, a, m[i + 14], 23, -35309556);
        a = HH(a, b, c, d, m[i + 1], 4, -1530992060);
        d = HH(d, a, b, c, m[i + 4], 11, 1272893353);
        c = HH(c, d, a, b, m[i + 7], 16, -155497632);
        b = HH(b, c, d, a, m[i + 10], 23, -1094730640);
        a = HH(a, b, c, d, m[i + 13], 4, 681279174);
        d = HH(d, a, b, c, m[i + 0], 11, -358537222);
        c = HH(c, d, a, b, m[i + 3], 16, -722521979);
        b = HH(b, c, d, a, m[i + 6], 23, 76029189);
        a = HH(a, b, c, d, m[i + 9], 4, -640364487);
        d = HH(d, a, b, c, m[i + 12], 11, -421815835);
        c = HH(c, d, a, b, m[i + 15], 16, 530742520);
        b = HH(b, c, d, a, m[i + 2], 23, -995338651);
        a = II(a, b, c, d, m[i + 0], 6, -198630844);
        d = II(d, a, b, c, m[i + 7], 10, 1126891415);
        c = II(c, d, a, b, m[i + 14], 15, -1416354905);
        b = II(b, c, d, a, m[i + 5], 21, -57434055);
        a = II(a, b, c, d, m[i + 12], 6, 1700485571);
        d = II(d, a, b, c, m[i + 3], 10, -1894986606);
        c = II(c, d, a, b, m[i + 10], 15, -1051523);
        b = II(b, c, d, a, m[i + 1], 21, -2054922799);
        a = II(a, b, c, d, m[i + 8], 6, 1873313359);
        d = II(d, a, b, c, m[i + 15], 10, -30611744);
        c = II(c, d, a, b, m[i + 6], 15, -1560198380);
        b = II(b, c, d, a, m[i + 13], 21, 1309151649);
        a = II(a, b, c, d, m[i + 4], 6, -145523070);
        d = II(d, a, b, c, m[i + 11], 10, -1120210379);
        c = II(c, d, a, b, m[i + 2], 15, 718787259);
        b = II(b, c, d, a, m[i + 9], 21, -343485551);
        a = (a + aa) >>> 0;
        b = (b + bb) >>> 0;
        c = (c + cc) >>> 0;
        d = (d + dd) >>> 0;

    }

    return [a, b, c, d];
}

/*
 * (c) 2011 by md5file.com. All rights reserved.
 */

self.hash = [1732584193, -271733879, -1732584194, 271733878];

self.addEventListener('message', function (event) {

    var uint8_array, message, block, output, nBitsTotal, nBitsLeft, nBitsTotalH, nBitsTotalL;

    uint8_array = new Uint8Array(event.data.message);
    message = Crypto.util.endian(Crypto.util.bytesToWords(uint8_array));
    block = event.data.block;
    event = null;
    uint8_array = null;
    output = {
        'block': block
    };

    if (block.end === block.file_size) {

        nBitsTotal = block.file_size * 8;
        nBitsLeft = (block.end - block.start) * 8;

        // Add padding
        message[nBitsLeft >>> 5] |= 0x80 << (nBitsLeft % 32);

        nBitsTotalH = Math.floor(nBitsTotal / 0x100000000);
        nBitsTotalL = nBitsTotal & 0xFFFFFFFF;

        message[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotalH;
        message[(((nBitsLeft + 64) >>> 9) << 4) + 14] = nBitsTotalL;

        self.hash = md5(message, self.hash);

        output.result = Crypto.util.bytesToHex(Crypto.util.wordsToBytes(Crypto.util.endian(self.hash)));
    } else {
        self.hash = md5(message, self.hash);
    }
    message = null;

    self.postMessage(output);
}, false);